package com.qf.utils;

import com.qf.mapper.UserMapper;
import com.qf.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

/**
 * @author Kuke
 * @date 2022/3/18 16:18
 * 工具类---获取mapper接口代理对象
 *
 * --SqlSession执行对象获取getMapper(接口Mapper)--->代理对象
 */
public class MyBatisUtils {
        //创建一个ThreadLocal<SqlSession>执行对象---->底层获取连接对象 控制事务
    private static ThreadLocal<SqlSession> t1 = new ThreadLocal<>() ;
    private static SqlSessionFactory sqlSessionFactory ;//声明了
    private static SqlSession sqlSession ;


    //构造方法私有化
    private MyBatisUtils(){}

    //静态代码块
    static{
        //1)读取核心配置文件
        try {
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            //创建sqlSessionFactoryBuilder对象: 构建者
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder() ;
            sqlSessionFactory = builder.build(inputStream) ;
            //创建执行对象
            sqlSession = sqlSessionFactory.openSession();//开启手动提交
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //定义功能,获取执行对象SqlSession
    public static SqlSession openSession(){
        //每一个线程都是自己的SqlSession
        //从当线程中获取SqlSession
        SqlSession sqlSession = t1.get();
        //判断如果null ,
        if(sqlSession ==null){
            //获取SqlSession对象,从sqlSessionFactory创建SqlSession
            sqlSession = sqlSessionFactory.openSession();
            //将获取的sqlSession绑定到当前线程上
            t1.set(sqlSession);

        }
        return sqlSession ;
    }

    //关闭SqlSession资源
    public static void closeSqlSession(){
        // //从当线程中获取SqlSession
        SqlSession sqlSession = t1.get();
        sqlSession.close();
        //将它从本地线程中进行解绑
        t1.remove();
    }
    //提交事务
    public static void commit(){
        //调用自己的封装openSession
        SqlSession sqlSession = openSession();
        //手动提交事务
        sqlSession.commit();
        //将sqlSession关闭
        closeSqlSession();
    }

    //回滚事务
    public static void rollback(){
        //调用自己的封装openSession
        SqlSession sqlSession = openSession();
        //手动提交事务
        sqlSession.rollback();
        //将sqlSession关闭
        closeSqlSession();
    }

    //通过mybatis动态代理获取接口地下
    //返回的类型:可以是任意Java对象
    public static <T extends Object> T getMapper(Class<T> clazz){
        //获取代理对象
        return sqlSession.getMapper(clazz) ; //mybatis动态代理
    }

}
